/**
 * @file matchMedia.js
 */


var $ = Zepto;

/**
 * 是原生的window.matchMedia方法的polyfill，对于不支持matchMedia的方法系统和浏览器，按照[w3c window.matchMedia](http://www.w3.org/TR/cssom-view/#dom-window-matchmedia)的接口
 * 定义，对matchMedia方法进行了封装。原理是用css media query及transitionEnd事件来完成的。在页面中插入media query样式及元素，当query条件满足时改变该元素样式，同时这个样式是transition作用的属性，
 * 满足条件后即会触发transitionEnd，由此创建MediaQueryList的事件监听。由于transition的duration time为0.001ms，故若直接使用MediaQueryList对象的matches去判断当前是否与query匹配，会有部分延迟，
 * 建议注册addListener的方式去监听query的改变。$.matchMedia的详细实现原理及采用该方法实现的转屏统一解决方案详见
 * [GMU Pages: 转屏解决方案($.matchMedia)](https://github.com/gmuteam/GMU/wiki/%E8%BD%AC%E5%B1%8F%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88$.matchMedia)
 *
 * 返回值MediaQueryList对象包含的属性<br />
 * - ***matches*** 是否满足query<br />
 * - ***query*** 查询的css query，类似\'screen and (orientation: portrait)\'<br />
 * - ***addListener*** 添加MediaQueryList对象监听器，接收回调函数，回调参数为MediaQueryList对象<br />
 * - ***removeListener*** 移除MediaQueryList对象监听器<br />
 *
 *
 * @method $.matchMedia
 * @grammar $.matchMedia(query)  ⇒ MediaQueryList
 * @param {String} query 查询的css query，类似\'screen and (orientation: portrait)\'
 * @return {Object} MediaQueryList
 * @example
 * $.matchMedia('screen and (orientation: portrait)').addListener(fn);
 */
$.matchMedia = (function () {
    var mediaId = 0;
    var cls = 'sf-edu-wenku-gmu-media-detect';
    var transitionEnd = $.fx.transitionEnd;
    var cssPrefix = $.fx.cssPrefix;
    var $style = $('<style></style>').append('.' + cls + '{' + cssPrefix + 'transition: width 0.001ms; width: 0; position: absolute; clip: rect(1px, 1px, 1px, 1px);}\n')
         .appendTo($(vw.container).find('.sfa-head'));

    return function (query) {
        var id = cls + mediaId++;
        var $mediaElem;
        var listeners = [];
        var ret;

        $style.append('@media ' + query + ' { .sf-edu-wenku-id-' + id + ' { width: 1px; } }\n'); // 原生matchMedia也需要添加对应的@media才能生效

        // 统一用模拟的，时机更好。
        // if ('matchMedia' in window) {
        //     return window.matchMedia(query);
        // }

        $mediaElem = $('<div class="' + cls + ' sf-edu-wenku-id-' + id + '"></div>')
            .appendTo(vw.container)
            .on(transitionEnd, function () {
                ret.matches = $mediaElem.width() === 1;
                $.each(listeners, function (i, fn) {
                    $.isFunction(fn) && fn.call(ret, ret);
                });
            });

        ret = {
            matches: $mediaElem.width() === 1,
            media: query,
            addListener: function (callback) {
                listeners.push(callback);
                return this;
            },
            removeListener: function (callback) {
                var index = listeners.indexOf(callback);
                ~index && listeners.splice(index, 1);
                return this;
            }

        };

        return ret;
    };
}());
